package ControlLayer;

import java.util.HashMap;
import java.util.Iterator;
import java.lang.StringBuilder;
import ModelLayer.*;

/**
 * This class is part of an address book system. It functions as a controller for the DVDCon class in
 * the ModelLayer. Any changes to DVDCon, DVD or Copy classes will go through this class.
 * This class is used through the system UI, more specifically DvdUI.
 *
 * @author Anders A.P., Anna K., Danny M.P., Jakob K., Mie P.  
 * @version 1.1
 *          1.1 update:     Made changes to updatePerson(), requiring the method to return a boolean value.
 *                          This method now provides proper logic when used in other methods.
 *                              
 */
public class DVDCtr
{
    private DVDCon dvdCon;

    /**
     * Constructs an instance of class DVDCtr, taking no parameters. Takes an instance of the singleton class DVDCon.
     */    
    public DVDCtr()
    {
        dvdCon = DVDCon.getInstance();
    }

    /**
     * Finds an object of class DVD, taking the follow parameter:
     *
     * @param   id          DVD objects ID, using this as a key in the HashMap dvdCon.
     * @return  String      Returns a String object.
     */    
    public String findDVDID(int id)
    {
        return DVDInfo(id);
    }
    
    /**
     * Finds an object of class DVD, taking the follow parameter:
     *
     * @param   title       DVD objects title.
     * @return  String      Returns a String object.
     */     
    public String findDVDTitle(String title)
    {
        DVD dvd = dvdCon.getDVDTitle(title);
        int id = dvd.getID();
        return DVDInfo(id);
    }

    /**
     * Returns a HashMap containing Copy objects contained within a given DVD object.
     *
     * @param   title   DVD title.
     * @return  HashMap Returns a HashMap of Copy objects associated with the DVD object.
     */    
    public HashMap<Integer, Copy> findCopy(String title)
    {
        DVD d = dvdCon.getDVDTitle(title);
        return d.getCopies();
    }

    /**
     * Generates a String with all information about a DVD object and its copies.
     *
     * @param   id      DVD ID.
     * @return String   A string that contains all information about the DVD.     
     */    
    private String DVDInfo(int id)
    {
        DVD                    dvd = dvdCon.getDVDID(id);
        HashMap<Integer, Copy> copies = dvd.getCopies();
        StringBuilder          stringBuilder = new StringBuilder();
        stringBuilder.append(dvd.getID() + "\n" +
                             dvd.getTitle() + "\n" +
                             dvd.getArtist() + "\n" +
                             dvd.getPubDate() + "\n");
        if(copies != null) {
            for(Copy c : copies.values()) {
                stringBuilder.append("Copy: " + c.getSerialNr() + "\n" +
                                                c.getPurchaseDate() + "\n" +
                                                c.getPurchasePrice() + "\n");
            }
        }        
        return stringBuilder.toString();
    }

    /**
     * Creates an instance of DVD and adds it to the container, taking the following parameters:
     * 
     * @param   title   DVD title.
     * @param   artist  DVD artist.
     * @param   pubDate DVD publishing date.
     */    
    public void createDVD(String title, String artist, String pubDate)
    {
        DVD dvd = new DVD(title, artist, pubDate);
        dvdCon.addDVD(dvd);
    }
    
    /**
     * Creates an instance of Copy and adds it to the container
     *
     * @param   dvdID       DVD ID.
     * @param   serialNo    Copy serial number.
     * @param   purDate     Copy purchase date.
     * @param   purPrice    Copy purchase price. 
     */
    public void createCopy(int dvdID, int serialNo, String purDate, double purPrice)
    {
        DVD d = dvdCon.getDVDID(dvdID);
        Copy    c = new Copy(serialNo, purDate, purPrice);
        d.addFiles(serialNo, c);
    }
    
    /**
     * Finds DVD by title, removes it from the collection then creates and adds a new 
     * DVD object to the collection.
     * 
     * @param   oldTitle    DVD old title.
     * @param   title       DVD title.
     * @param   artist      DVD artist.
     * @param   pubDate     DVD publishing date.
     */
    public void updateDVD(String oldTitle, String newTitle, String artist, String pubDate)
    {        
        DVD dvd = dvdCon.getDVDTitle(oldTitle);
        dvd.setTitle(newTitle);
        dvd.setArtist(artist);
        dvd.setPubDate(pubDate);
    }
    
    /**
     * Finds Copy by serialNumber, removes it from the collection then creates and adds a new 
     * Copy object to the collection in the DVD.
     * 
     * @param dvdID         DVD ID.
     * @param serialNumber  Copy serial number.
     * @param purDate       Copy purchase date.
     * @param purPrice      Copy purchase price.
     */
    public void updateCopy(int dvdID, int serialNumber, String purDate, double purPrice)
    {
        DVD tempDVD = null;;
        for(DVD dvd : dvdCon.getMap().values()) {
            if(dvd.getID() == dvdID) {
                tempDVD = dvd;
            }
            if (tempDVD.getCopy(serialNumber) != null) {
                tempDVD.getCopy(serialNumber).setPurchaseDate(purDate);
                tempDVD.getCopy(serialNumber).setPurchasePrice(purPrice);
            }
        }
    }

    /**
     * Deletes a DVD using its ID as a key.
     * 
     * @param   dvdID   The ID of the DVD to be deleted.
     * @return  false   If the DVD has not been deleted form the collection.
     * @return  true    If the DVD has been deleted from the collection.
     */
    public boolean deleteDVD(int dvdID)
    {
        return dvdCon.deleteDVD(dvdID);
    }

    /**
     * Returns a list of all DVD objects contained in the collection.
     *
     * @return  String  A list of all dvds in the dvdCon collection.
     */
    public String listAllDvds()
    {
        String s = "";
        for(DVD d: dvdCon.getMap().values()) {
            s += DVDInfo(d.getId());
        }
        return s;
    }
}